#include "reg51.h"

#include "app_config.h"

static volatile uint32_t system_tick = 0;

sbit    TEST_LED = P2 ^ 0;   // work LED, flash once per second

sbit    KEY      = P3 ^ 7;   // 定义画面切换按键
uint8_t KY;                  // KY作用在后面说明
uint8_t pic = 0;    // pic为按键次数；

uint8_t code love[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x20, 0x00, 0x20,
    0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0xF8, 0x0F, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x04, 0x10,
    0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x08, 0x00, 0x10, 0x00,
    0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xFE, 0x3F, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82, 0x20, 0x82,
    0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*LOVE*/
};

uint8_t code loveyou[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x78, 0x00, 0xFC, 0x00, 0xFE, 0x01, 0xFE, 0x03, 0xFE, 0x07, 0xFE, 0x0F,
    0xFE, 0x1F, 0xFC, 0x3F, 0xF8, 0x7F, 0xFC, 0x3F, 0xFE, 0x1F, 0xFE, 0x0F, 0xFE, 0x07, 0xFE,
    0x03, 0xFE, 0x01, 0xFC, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*心形图案*/
};

uint8_t code hehe[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x40, 0x01, 0xC0, 0x01, 0x00, 0x00,
    0x00, 0x00, 0xF0, 0x0F, 0x08, 0x10, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x08,
    0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xF0,
    0x3F, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0xF0, 0x3F, 0x00, 0x00,
    0x00, 0x00, 0x04, 0x20, 0x08, 0x10, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x40,
    0x01, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*呵呵o(∩_∩)o图案*/
};

uint8_t code hanzi[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, /*" ",1*/
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, /*" ",1*/

    0x20, 0x01, 0x10, 0x01, 0x2C, 0x01, 0xE7, 0x7F, 0x24, 0x21, 0x24,
    0x11, 0x00, 0x00, 0xF0, 0x07, 0x10, 0x02, 0x10, 0x02, 0xFF, 0xFF,
    0x10, 0x02, 0x10, 0x02, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, /*"钟",0*/

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, /*" ",1*/
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, /*" ",1*/

    0x22, 0x80, 0x2A, 0x60, 0xAA, 0x08, 0xFF, 0x0A, 0xAA, 0x6A, 0xAA,
    0x8A, 0xA2, 0x8A, 0x80, 0x9A, 0xA2, 0xAA, 0xAA, 0x8A, 0xAA, 0x8A,
    0xFF, 0xCA, 0xAA, 0x0F, 0x2A, 0x20, 0x22, 0xC0, 0x00, 0x00, /*"慧",2*/

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, /*" ",1*/
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, /*" ",1*/
};

/*****函数声明*****/
void display1_ltor(void);
void display2_ltor(void);
void display2_rtol(void);
void display3(void);
void display4(void);

/*****n（us）延时子程序*****/
void DelayUs(uint16_t n)
{
    uint16_t x;
    for (x = 0; x <= n; x++);
}

/*****显示子程序1（汉字）*****/
void display1_ltor(void)
{
    uint8_t i;

    DelayUs(4000);   // 此处延时时间依各硬件差别而各不相同，试着调整使得显示内容居中即可

    for (i = 0; i < sizeof(hanzi); i++) {
        P0 = ~hanzi[i * 2];
        P2 = ~hanzi[i * 2 + 1];
        DelayUs(50);
    }
}

/*****显示子程序2（LOVE）*****/
void display2_ltor(void)
{
    uint8_t i;

    DelayUs(4000);
    for (i = 0; i < 64; i++) {
        P0 = ~love[i * 2];
        P2 = ~love[i * 2 + 1];
        DelayUs(140);
    }
}
/*****显示子程序3（心形图案）*****/
void display3(void)
{
    uint8_t i;
    DelayUs(4000);
    for (i = 0; i < 64; i++) {
        P0 = ~loveyou[i * 2];
        P2 = ~loveyou[i * 2 + 1];
        DelayUs(120);
    }
}

/*****显示子程序4（呵呵o(∩_∩)o图案）*****/
void display4(void)
{
    uint8_t i;
    DelayUs(4000);
    for (i = 0; i < 64; i++) {
        P0 = ~hehe[i * 2];
        P2 = ~hehe[i * 2 + 1];
        DelayUs(120);
    }
}

/*****中断服务程序*****/
void intersvr0(void) interrupt 0
{
    ;
    // 每个摇动来回水银开关会在摆幅两端分别产生下降沿中断，只提取其中一次（从左向右摇才显示）
    KY = 1;
}

#if ENABLE_TIMER1
void timer1_timeout_isr() interrupt 3
{
    TL1 = TIMER1_TIMEOUT;        // reload timer1 low byte
    TH1 = TIMER1_TIMEOUT >> 8;   // reload timer1 high byte

    system_tick++;
}
#endif

void app_key_scan(void)
{
    static uint8_t step            = 0;
    static uint8_t key_delay_count = 0;

    switch (step) {
        case 0x00: {
            if (KEY == 0) {
                step            = 0x01;
                key_delay_count = 0;
            }
        } break;
        case 0x01: {
            if (KEY == 0) {
                key_delay_count++;
                if (key_delay_count >= 4) {
                    key_delay_count = 0;
                    step            = 0x02;

                    // 按键按下
                    pic++;
                    if (pic > 3) {
                        pic = 0;
                    }
                }
            }
            else {
                key_delay_count = 0;
                step            = 0x00;
            }
        } break;
        case 0x02: {
            if (KEY != 0) {
                step = 0x00;

                // 按键释放
            }
        } break;
        default: break;
    }
}

void app_led_disp(void)
{
    if (KY) {
        switch (pic) {
            case 0: {
                display1_ltor();
            } break;
            case 1: {
                display2_ltor();
            } break;
            case 2: {
                display3();
            } break;
            case 3: {
                display4();
            } break;
            default: {
                display1_ltor();
            } break;
        }
        KY = 0;
    }
}

/*****主函数*****/
void main(void)
{
    system_tick = 0;

    IT0 = 1;
    EX0 = 1;

#if ENABLE_TIMER1
    TMOD = 0x10;                  // set timer1 as mode1 (16-bit)
    TL1  = TIMER1_TIMEOUT;        // initial timer1 low byte
    TH1  = TIMER1_TIMEOUT >> 8;   // initial timer1 high byte
    TR1  = 1;                     // timer1 start running
    ET1  = 1;                     // enable timer1 interrupt
#endif

    EA = 1;   // 开中断，下降沿中断
    KY = 0;

    while (1) {
        if (system_tick >= 5) {
            system_tick = 0;

            app_key_scan();

            app_led_disp();
        }
    }
}
/*****END*****/
